package ntd.util.frame.data.factory;

import cn.hutool.core.util.EnumUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.db.Db;
import cn.hutool.db.Entity;
import cn.hutool.db.ds.DSFactory;
import cn.hutool.db.ds.hikari.HikariDSFactory;
import cn.hutool.log.StaticLog;
import cn.hutool.setting.Setting;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import com.zaxxer.hikari.pool.HikariPool;
import ntd.util.ComConfig;
import ntd.util.config.common.enums.data.EnumDataSourceType;
import ntd.util.config.common.exception.ComException;
import ntd.util.util.ToolDuration;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;


@Component
public class FactoryData {

    private static final Map<String, HikariDataSource> HIKARI_DATA_SOURCE_MAP = new HashMap<>();

    public static final String DATA_URL_PARAM = "?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=GMT%2B8";

    private static final Setting SETTING = new Setting();

    public static DataSource dataSource() {
        return initDataSource("me");
    }

    public static DataSource initDataSource(String dsId) {
        HikariDataSource hikariDataSource = HIKARI_DATA_SOURCE_MAP.get(dsId);
        if (ObjectUtil.isNull(hikariDataSource)) {
            HikariConfig hikariConfig = new HikariConfig();
            if (dsId.equals("me")) {
                hikariConfig.setJdbcUrl(ComConfig.com.getStr("spring.datasource.url"));
                hikariConfig.setUsername(ComConfig.com.getStr("spring.datasource.username"));
                hikariConfig.setPassword(ComConfig.com.getStr("spring.datasource.password"));
            } else {
                Entity dataSourceEntity = null;
                try {
                    dataSourceEntity = FactoryData.db().findBy("data_source", "id", dsId).get(0);
                } catch (SQLException e) {
                    StaticLog.error(e, "[FactoryData][初始化][{}]失败...");
                    throw new ComException("查询数据源失败...");
                }
                EnumDataSourceType enumDataSourceType = EnumDataSourceType.valueOf(dataSourceEntity.getStr("enum_data_source_type"));

                hikariConfig.setJdbcUrl(jdbcUrl(enumDataSourceType.jdbcPrefix(), dataSourceEntity.getStr("link_address")));
                hikariConfig.setUsername(dataSourceEntity.getStr("account"));
                hikariConfig.setPassword(dataSourceEntity.getStr("password"));
            }
            hikariConfig.setMaximumPoolSize(8);
            hikariConfig.setMaxLifetime(300000);
            hikariConfig.setConnectionTestQuery("SELECT 1");

            hikariDataSource = new HikariDataSource(hikariConfig);
            HIKARI_DATA_SOURCE_MAP.put(dsId, hikariDataSource);
        }
        return hikariDataSource;
    }

    public static DataSource dataSource(String dsId) {
        if (StrUtil.isBlank(dsId)) {
            return dataSource();
        }
        return initDataSource(dsId);
    }

    public static String jdbcUrl(String prefix, String linkAddress) {
        return StrUtil.format("{}{}{}", prefix, linkAddress, DATA_URL_PARAM);
    }

    public static Db db() {
        return Db.use(dataSource());
    }

    public static void main(String[] args) {
        Setting setting = new Setting();
        // jdbc:mysql://rm-bp1qo4jg2q6wi1q7olo.mysql.rds.aliyuncs.com/ntd_server
        // jdbc:mysql//47.111.147.207:3306/efp
        setting.set("jdbcUrl", "jdbc:mysql://47.111.147.207:3306/efp?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=GMT%2B8");
        setting.set("username", "root");
        setting.set("password", "efp.mysql");
        HikariDSFactory hikariDSFactory = new HikariDSFactory(setting);

        setting.setByGroup("jdbcUrl", "dsId", "jdbc:mysql://47.111.147.207:3306/efp?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=GMT%2B8");
        setting.setByGroup("username", "dsId", "root");
        setting.setByGroup("password", "dsId", "efp.mysql");

        hikariDSFactory.getDataSource();
        DataSource dsId = hikariDSFactory.getDataSource("dsId");
    }

}
